﻿#region License statement
// NJamb, a specification and delta-specification DSL
// Copyright (c) 2010-2011, Mark Knell
// Published under the MIT License; all other rights reserved
#endregion

#region using...
using System;
using NJamb.Specifications;
using Stile.Patterns.SelfDescribingPredicates;
using Stile.Patterns.SelfDescribingPredicates.Evaluators;
using Stile.Types.Equality;
#endregion

namespace NJamb.Parser.SpecificationBuilders.SubjectIs.Extensions
{
    public static class IsComparableExtensions
    {
        public static TSpecifies ComparablyEqualTo<TSubject, TSpecifies>(this IFluentIs<TSubject, TSpecifies> collaboratingIs,
            TSubject other) where TSubject : IComparable<TSubject> where TSpecifies : class, ISpecification<TSubject>
        {
            var evaluator = new SimpleEvaluator<TSubject>(other,
                x => x.IsComparablyEqualTo(other),
                collaboratingIs.Xray.Negated,
                VerbTensePair.WouldBeButWas);
            return collaboratingIs.Xray.SpecificationBuilder.Specify(evaluator);
        }

        public static TSpecifies GreaterThan<TSubject, TSpecifies>(this IFluentIs<TSubject, TSpecifies> collaboratingIs,
            TSubject other) where TSubject : IComparable<TSubject> where TSpecifies : class, ISpecification<TSubject>
        {
            var evaluator = new SimpleEvaluator<TSubject>(other,
                x => x.IsGreaterThan(other),
                collaboratingIs.Xray.Negated,
                VerbTensePair.WouldBeGreaterThanButWas);
            return collaboratingIs.Xray.SpecificationBuilder.Specify(evaluator);
        }

        public static TSpecifies GreaterThanOrEqualTo<TSubject, TSpecifies>(this IFluentIs<TSubject, TSpecifies> collaboratingIs,
            TSubject other) where TSubject : IComparable<TSubject> where TSpecifies : class, ISpecification<TSubject>
        {
            var evaluator = new SimpleEvaluator<TSubject>(other,
                x => x.IsGreaterThanOrEqualTo(other),
                collaboratingIs.Xray.Negated,
                VerbTensePair.WouldBeGreaterThanOrEqualToButWas);
            return collaboratingIs.Xray.SpecificationBuilder.Specify(evaluator);
        }

        public static TSpecifies LessThan<TSubject, TSpecifies>(this IFluentIs<TSubject, TSpecifies> collaboratingIs,
            TSubject other) where TSubject : IComparable<TSubject> where TSpecifies : class, ISpecification<TSubject>
        {
            var evaluator = new SimpleEvaluator<TSubject>(other,
                x => x.IsLessThan(other),
                collaboratingIs.Xray.Negated,
                VerbTensePair.WouldBeLessThanButWas);
            return collaboratingIs.Xray.SpecificationBuilder.Specify(evaluator);
        }

        public static TSpecifies LessThanOrEqualTo<TSubject, TSpecifies>(this IFluentIs<TSubject, TSpecifies> collaboratingIs,
            TSubject other) where TSubject : IComparable<TSubject> where TSpecifies : class, ISpecification<TSubject>
        {
            var evaluator = new SimpleEvaluator<TSubject>(other,
                x => x.IsLessThanOrEqualTo(other),
                collaboratingIs.Xray.Negated,
                VerbTensePair.WouldBeLessThanOrEqualToButWas);
            return collaboratingIs.Xray.SpecificationBuilder.Specify(evaluator);
        }
    }
}
